﻿#region zh-CHS 2006 - 2007 DemoSoft 团队 | en 2006 - 2007 DemoSoft Team

//     NOTES
// ---------------
//
// This file is a part of the G.O.S.E(Game Online Server Engine) for .NET.
//
//                 2006-2007 DemoSoft Team
//
//
// First Version : by H.Q.Cai - mailto:caihuanqing@hotmail.com

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

#region zh-CHS 包含名字空间 | en Include namespace
using System;
using System.Text;
using System.Threading;
using System.Reflection;
using System.Diagnostics;
using System.ComponentModel;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Demo_G.O.S.E.ServerEngine.Map;
using Demo_G.O.S.E.ServerEngine.Util;
using Demo_G.O.S.E.ServerEngine.World;
using Demo_G.O.S.E.ServerEngine.Mobile;
using Demo_G.O.S.E.ServerEngine.Common;
using Demo_G.O.S.E.ServerEngine.Network;
#endregion

namespace Demo_G.O.S.E.ServerEngine.Item
{
    // 道具的信息
    //////////////////////////////////////////////////////////////////////////
    // 道具(单一)
    // 道具(容器)
    // 
    // 
    // 

    // 道具的行为
    //////////////////////////////////////////////////////////////////////////
    // 道具(交易-玩家)
    // 道具(装备-玩家)
    // 道具(容器-道具)
    // 道具(位置-地图)
    // 道具(存在/消失-地图)
    // 道具(其它)
    // 
    // 

    /// <summary>
    /// 
    /// </summary>
    public class BaseItem : IEntity, IComparable, IComparable<BaseItem>
    {
        #region zh-CHS 构造和初始化和清理 | en Constructors and Initializers and Dispose
        /// <summary>
        /// 
        /// </summary>
        public BaseItem()
        {
            DefaultItemInit();
            DefaultDeltaInit();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serial"></param>
        public BaseItem( Serial serial ) : this()
        {
            m_Serial = serial;
            DefaultItemInit();
            DefaultDeltaInit();
        }

        #region zh-CHS 道具的初始化 | en
        /// <summary>
        /// 缺省的初始化人物
        /// </summary>
        protected virtual void DefaultItemInit()
        {
        }

        /// <summary>
        /// 缺省的初始化人物
        /// </summary>
        protected virtual void DefaultDeltaInit()
        {
        }
        #endregion

        #endregion

        #region zh-CHS 属性 | en Properties

        #region zh-CHS X属性 | en Public Properties

        /// <summary>
        /// 道具的X坐标点
        /// </summary>
        [CommandProperty( AccessLevel.Counselor, AccessLevel.GameMaster )]
        public long X
        {
            get { return m_Location.X; }
            set { UpdateItem( UpdateBaseItemValue.X, value ); }
        }

        #endregion

        #region zh-CHS Y属性 | en Public Properties

        /// <summary>
        /// 道具的Y坐标点
        /// </summary>
        [CommandProperty( AccessLevel.Counselor, AccessLevel.GameMaster )]
        public long Y
        {
            get { return m_Location.Y; }
            set { UpdateItem( UpdateBaseItemValue.Y, value ); }
        }

        #endregion

        #region zh-CHS Z属性 | en Public Properties

        /// <summary>
        /// 道具的Z坐标点
        /// </summary>
        [CommandProperty( AccessLevel.Counselor, AccessLevel.GameMaster )]
        public long Z
        {
            get { return m_Location.Z; }
            set { UpdateItem( UpdateBaseItemValue.Z, value ); }
        }

        #endregion

        #region zh-CHS Location属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private Point3D m_Location = new Point3D();
        #endregion
        /// <summary>
        /// 道具在地图上面的坐标点
        /// </summary>
        [CommandProperty( AccessLevel.Counselor, AccessLevel.GameMaster )]
        public virtual Point3D Location
        {
            get { return m_Location; }
            set { UpdateItem( UpdateBaseItemValue.Location, value ); }
        }

        #endregion

        #region zh-CHS Direction属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private long m_Direction = 0;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        [CommandProperty( AccessLevel.GameMaster )]
        public long Direction
        {
            get { return m_Direction; }
            set { UpdateItem( UpdateBaseItemValue.Direction, value ); }
        }

        #endregion

        #region zh-CHS Serial属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private Serial m_Serial = new Serial();
        #endregion
        /// <summary>
        /// 道具的唯一序列号GUID
        /// </summary>
        [CommandProperty( AccessLevel.Counselor )]
        public Serial Serial
        {
            get { return m_Serial; }
            set { UpdateItem( UpdateBaseItemValue.Serial, value ); }
        }

        #endregion

        #region zh-CHS Map属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private BaseMap m_BaseMap = BaseMap.NullMap;
        #endregion
        /// <summary>
        /// 地图的位置
        /// </summary>
        [CommandProperty( AccessLevel.Counselor, AccessLevel.GameMaster )]
        public BaseMap Map
        {
            get { return m_BaseMap; }
            set { UpdateItem( UpdateBaseItemValue.Map, value ); }
        }

        #endregion

        #region zh-CHS Name属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private string m_Name = string.Empty;
        #endregion
        /// <summary>
        /// 道具的名字
        /// </summary>
        [CommandProperty( AccessLevel.GameMaster )]
        public string Name
        {
            get { return m_Name; }
            set { UpdateItem( UpdateBaseItemValue.Name, value ); }
        }

        #endregion

        #region zh-CHS Visible属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private bool m_Visible = true;
        #endregion
        /// <summary>
        /// 是否可见
        /// </summary>
        [CommandProperty( AccessLevel.GameMaster )]
        public bool Visible
        {
            get { return m_Visible; }
            set { UpdateItem( UpdateBaseItemValue.Visible, value ); }
        }

        #endregion

        #region zh-CHS Parent属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private object m_Parent = null; // BaseMobile, BaseItem, or null=World
        #endregion
        /// <summary>
        /// 拥有者的对象
        /// </summary>
        public virtual object Parent
        {
            get { return m_Parent; }
            set { UpdateItem( UpdateBaseItemValue.Parent, value ); }
        }

        #endregion

        #region zh-CHS Layer属性 | en Public Properties

        #region zh-CHS 私有静态成员变量 | en Private Static Member Variables
        /// <summary>
        /// 
        /// </summary>
        private Layer m_Layer;
        #endregion
        /// <summary>
        /// 道具使用在身体上的部位
        /// </summary>
        [CommandProperty( AccessLevel.GameMaster )]
        public virtual Layer Layer
        {
            get { return m_Layer; }
            set { UpdateItem( UpdateBaseItemValue.Layer, value ); }
        }

        #endregion

        #region zh-CHS IsVirtualItem属性 | en Public Properties

        #region zh-CHS 私有静态成员变量 | en Private Static Member Variables
        /// <summary>
        /// 
        /// </summary>
        private bool m_IsVirtualItem = false;
        #endregion
        /// <summary>
        /// 是否是不可见的道具
        /// </summary>
        public virtual bool IsVirtualItem
        {
            get { return m_IsVirtualItem; }
            set { UpdateItem( UpdateBaseItemValue.IsVirtualItem, value ); }
        }

        #endregion

        #region zh-CHS ItemDelta属性 | en Public Properties

        #region zh-CHS 私有静态成员变量 | en Private Static Member Variables
        /// <summary>
        /// 人物的状态机
        /// </summary>
        private IItemDelta m_ItemDelta = new BaseItemDelta();
        #endregion
        /// <summary>
        /// 人物的状态机
        /// </summary>
        public IItemDelta ItemDelta
        {
            get { return m_ItemDelta; }
        }

        #endregion

        #region zh-CHS 子道具列表 属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 人物的道具列表
        /// </summary>
        private Dictionary<long, BaseItem> m_ChildItems = new Dictionary<long, BaseItem>();
        /// <summary>
        /// 
        /// </summary>
        private object m_LockChildItems = new object();
        /// <summary>
        /// 全部好友
        /// </summary>
        private BaseItem[] m_ChildItemsArray = new BaseItem[0];
        /// <summary>
        /// 好友的集合数据是否已经改变过
        /// </summary>
        private bool m_bIsChildItemsChange = true;
        #endregion
        /// <summary>
        /// 人物的道具列表(包裹与身上)
        /// </summary>
        /// <returns></returns>
        [MultiThreadedWarningAttribute( "(子道具)当前的数组是列表临时产生的,不能保存数组用于以后操作:警告!" )]
        public BaseItem[] ChildItemsToArray()
        {
            BaseItem[] l_BaseItem = null;

            Monitor.Enter( m_LockChildItems );
            {
                if ( m_bIsChildItemsChange )
                {
                    l_BaseItem = new BaseItem[m_ChildItems.Count];

                    long iIndex = 0;
                    foreach ( KeyValuePair<long, BaseItem> keyValuePair in m_ChildItems )
                    {
                        l_BaseItem[iIndex] = keyValuePair.Value;
                        iIndex++;
                    }

                    m_bIsChildItemsChange = false;
                }
            }
            Monitor.Exit( m_LockChildItems );

            return l_BaseItem;
        }

        #region zh-CHS 内部保护方法 | en Protected Internal Methods
        /// <summary>
        /// 道具添加
        /// </summary>
        /// <param name="item"></param>
        protected virtual bool OnBeforeAddChildItem( BaseItem baseItem )
        {
            return true;
        }

        /// <summary>
        /// 道具添加
        /// </summary>
        /// <param name="item"></param>
        protected virtual void OnAfterAddChildItem( BaseItem baseItem )
        {
        }

        /// <summary>
        /// 道具移去
        /// </summary>
        /// <param name="item"></param>
        protected virtual bool OnBeforeRemoveChildItem( BaseItem baseItem )
        {
            return true;
        }

        /// <summary>
        /// 道具移去
        /// </summary>
        /// <param name="item"></param>
        protected virtual void OnAfterRemoveChildItem( BaseItem baseItem )
        {
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods

        /// <summary>
        /// 添加道具
        /// </summary>
        /// <param name="item"></param>
        public bool AddChildItem( BaseItem baseItem )
        {
            if ( m_Deleted )
                return false;

            if ( baseItem == null )
                return false;

            BaseItemDelta l_ItemDelta = m_ItemDelta as BaseItemDelta;
            if ( l_ItemDelta == null )
            {
                Debug.WriteLine( "BaseItem.AddItem(...) - l_ItemDelta == null error!" );
                return false;
            }

            bool l_Return = false;
            Monitor.Enter( m_LockChildItems );
            do
            {
                BaseItem l_BaseItem = null;

                if ( m_ChildItems.TryGetValue( baseItem.Serial, out l_BaseItem ) )
                {
                    l_Return = true;
                    break;
                }

                if ( l_BaseItem != null )
                {
                    l_Return = true;
                    break;
                }

                if ( OnBeforeAddChildItem( baseItem ) == false )
                {
                    l_Return = true;
                    break;
                }

                m_ChildItems.Add( baseItem.Serial, baseItem );

                baseItem.Parent = this;

                m_bIsChildItemsChange = true;
            } while ( false );
            Monitor.Exit( m_LockChildItems );

            if ( l_Return )
                return false;

            l_ItemDelta.UpdateAddChildItemCall();
            if ( l_ItemDelta.IsDeltaAddChildItemCall )
                UpdateDelta();

            OnAfterAddChildItem( baseItem );

            return true;
        }

        /// <summary>
        /// 移出道具
        /// </summary>
        /// <param name="item"></param>
        public bool RemoveChildItem( long iItemSerial )
        {
            if ( m_Deleted )
                return false;

            BaseItemDelta l_ItemDelta = m_ItemDelta as BaseItemDelta;
            if ( l_ItemDelta == null )
            {
                Debug.WriteLine( "BaseItem.RemoveItem(...) - l_ItemDelta == null error!" );
                return false;
            }

            bool l_Return = false;
            BaseItem l_BaseItem = null;
            Monitor.Enter( m_LockChildItems );
            do
            {
                if ( m_ChildItems.TryGetValue( iItemSerial, out l_BaseItem ) == false )
                {
                    l_Return = true;
                    break;
                }

                if ( l_BaseItem == null )
                {
                    l_Return = true;
                    break;
                }

                if ( OnBeforeRemoveChildItem( l_BaseItem ) == false )
                {
                    l_Return = true;
                    break;
                }

                m_ChildItems.Remove( iItemSerial );

                l_BaseItem.Parent = null;

                m_bIsChildItemsChange = true;
            } while ( false );
            Monitor.Exit( m_LockChildItems );

            if ( l_Return )
                return false;

            l_ItemDelta.UpdateRemoveChildItemCall();
            if ( l_ItemDelta.IsDeltaRemoveChildItemCall )
                UpdateDelta();

            OnAfterRemoveChildItem( l_BaseItem );

            return true;
        }

        /// <summary>
        /// 在身上找道具
        /// </summary>
        /// <param name="layer"></param>
        /// <returns></returns>
        public BaseItem[] FindChildItemOnLayer( Layer layer )
        {
            List<BaseItem> l_BaseItem = new List<BaseItem>();

            Monitor.Enter( m_LockChildItems );
            {
                foreach ( KeyValuePair<long, BaseItem> Item in m_ChildItems )
                {
                    if ( Item.Value.Deleted == false && Item.Value.Layer == layer )
                        l_BaseItem.Add( Item.Value );
                }
            }
            Monitor.Exit( m_LockChildItems );

            return l_BaseItem.ToArray();
        }

        /// <summary>
        /// 在身上找道具
        /// </summary>
        /// <param name="layer"></param>
        /// <returns></returns>
        public BaseItem FindChildItemOnSerial( long iItemSerial )
        {
            BaseItem l_BaseItem = null;

            Monitor.Enter( m_LockChildItems );
            {
                m_ChildItems.TryGetValue( iItemSerial, out l_BaseItem );
            }
            Monitor.Exit( m_LockChildItems );

            return l_BaseItem;
        }

        #endregion

        #endregion

        #region zh-CHS Deleted属性 | en Public Properties

        #region zh-CHS 私有静态成员变量 | en Private Static Member Variables
        /// <summary>
        /// 
        /// </summary>
        private bool m_Deleted = false;
        #endregion
        /// <summary>
        /// 当前的道具是否已经删除
        /// </summary>
        public bool Deleted
        {
            get { return m_Deleted; }
        }

        #region zh-CHS 内部保护方法 | en Protected Internal Methods
        /// <summary>
        /// 拥有者删除
        /// </summary>
        /// <param name="parent"></param>
        public virtual void OnParentDeleted( object parent )
        {
        }

        /// <summary>
        /// 删除道具时
        /// </summary>
        public virtual void OnDelete()
        {
        }

        /// <summary>
        /// 删除道具之后
        /// </summary>
        public virtual void OnAfterDelete()
        {
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        /// <summary>
        /// 删除道具
        /// </summary>
        public void Delete()
        {
            OnDelete();

            BaseItem[] l_BaseItemArray = ChildItemsToArray();
            if ( l_BaseItemArray != null )
            {
                foreach ( BaseItem baseItem in l_BaseItemArray )
                    baseItem.OnParentDeleted( this );
            }

            m_Deleted = true;

            OnAfterDelete();
        }
        #endregion

        #endregion

        #region zh-CHS Sector属性 | en Public Properties
        #region zh-CHS 私有静态成员变量 | en Private Static Member Variables
        /// <summary>
        /// 
        /// </summary>
        private Sector m_Sector = Sector.NullSector;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        internal Sector Sector
        {
            get { return m_Sector; }
            set { m_Sector = value; }
        }
        #endregion

        #region zh-CHS ISpawner属性 | en Public Properties
        #region zh-CHS 私有静态成员变量 | en Private Static Member Variables
        /// <summary>
        /// 
        /// </summary>
        private ISpawner m_Spawner = null;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public ISpawner Spawner
        {
            get { return m_Spawner; }
            set { m_Spawner = value; }
        }
        #endregion

        #endregion

        #region zh-CHS 方法 | en Method

        #region zh-CHS 给出人物范围内的道具或人物或对象 | en
        /// <summary>
        /// 给出人物范围内的道具
        /// </summary>
        /// <param name="range"></param>
        /// <returns></returns>
        public IPooledEnumerable GetItemsInRange( int iRange )
        {
            if ( m_BaseMap == null || m_BaseMap == BaseMap.NullMap )
                return NullEnumerable.Instance;

            return m_BaseMap.GetItemsInRange( m_Location, iRange );
        }

        /// <summary>
        /// 给出人物范围内的对象
        /// </summary>
        /// <param name="range"></param>
        /// <returns></returns>
        public IPooledEnumerable GetObjectsInRange( int iRange )
        {
            if ( m_BaseMap == null || m_BaseMap == BaseMap.NullMap )
                return NullEnumerable.Instance;

            return m_BaseMap.GetObjectsInRange( m_Location, iRange );
        }

        /// <summary>
        /// 给出人物范围内的人物
        /// </summary>
        /// <param name="range"></param>
        /// <returns></returns>
        public IPooledEnumerable GetMobilesInRange( int iRange )
        {
            if ( m_BaseMap == null || m_BaseMap == BaseMap.NullMap )
                return NullEnumerable.Instance;

            return m_BaseMap.GetMobilesInRange( m_Location, iRange );
        }

        /// <summary>
        /// 给出人物范围内的客户端
        /// </summary>
        /// <param name="range"></param>
        /// <returns></returns>
        public IPooledEnumerable GetClientsInRange( int iRange )
        {
            if ( m_BaseMap == null || m_BaseMap == BaseMap.NullMap )
                return NullEnumerable.Instance;

            return m_BaseMap.GetClientsInRange( m_Location, iRange );
        }
        #endregion

        #region zh-CHS 地图点激活方法 | en Protected Internal Methods
        /// <summary>
        /// 地图点激活
        /// </summary>
        protected internal virtual void OnSectorActivate()
        {
        }

        /// <summary>
        /// 地图点不激活
        /// </summary>
        protected internal virtual void OnSectorDeactivate()
        {
        }
        #endregion

        #region zh-CHS 跟新数据 | en Protected Methods

        #region zh-CHS 保护方法 | en Protected Methods
        /// <summary>
        /// 数据改变之前
        /// </summary>
        protected virtual bool OnBeforeChangeValue( UpdateBaseItemValue updateItem, object newValue )
        {
            switch ( updateItem )
            {
                case UpdateBaseItemValue.ItemDelta:
                    BaseItemDelta l_BaseItemDelta = newValue as BaseItemDelta;
                    if ( l_BaseItemDelta == null )
                    {
                        Debug.WriteLine( "BaseItem.OnBeforeChange(...) - l_BaseItemDelta == null error!" );
                        return false;
                    }
                    break;
                default:

                    break;
            }
            return true;
        }

        /// <summary>
        /// 数据改变中
        /// </summary>
        protected virtual void OnValidateValue( UpdateBaseItemValue updateItem, object value )
        {
            switch ( updateItem )
            {
                case UpdateBaseItemValue.X:
                    m_Location.X = (long)value;

                    break;
                case UpdateBaseItemValue.Y:
                    m_Location.Y = (long)value;

                    break;
                case UpdateBaseItemValue.Z:
                    m_Location.Z = (long)value;

                    break;
                case UpdateBaseItemValue.Location:
                    m_Location = (Point3D)value;

                    break;
                case UpdateBaseItemValue.Direction:
                    m_Direction = (long)value;

                    break;
                case UpdateBaseItemValue.Serial:
                    m_Serial = (Serial)value;

                    break;
                case UpdateBaseItemValue.Map:
                    m_BaseMap = (BaseMap)value;

                    break;
                case UpdateBaseItemValue.Name:
                    m_Name = (string)value;

                    break;
                case UpdateBaseItemValue.Visible:
                    m_Visible = (bool)value;

                    break;
                case UpdateBaseItemValue.Parent:
                    m_Parent = value;

                    break;
                case UpdateBaseItemValue.Layer:
                    m_Layer = (Layer)value;

                    break;
                case UpdateBaseItemValue.IsVirtualItem:
                    m_IsVirtualItem = (bool)value;

                    break;
                case UpdateBaseItemValue.ItemDelta:
                    m_ItemDelta = value as BaseItemDelta;

                    break;
                default:

                    break;
            }
        }

        /// <summary>
        /// 数据改变之后
        /// </summary>
        protected virtual void OnAfterChangeValue( UpdateBaseItemValue updateItem, object oldValue )
        {
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        /// <summary>
        /// 更新全部类型的数量
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="type"></param>
        /// <param name="delta"></param>
        public bool UpdateItem( UpdateBaseItemValue updateItem, object newValue )
        {
            if ( m_Deleted )
                return false;

            BaseItemDelta l_ItemDelta = m_ItemDelta as BaseItemDelta;
            if ( l_ItemDelta == null )
            {
                Debug.WriteLine( "BaseItem.UpdateBaseItem(...) - l_ItemDelta == null error!" );
                return false;
            }

            switch ( updateItem )
            {
                case UpdateBaseItemValue.X: // 当前地图的某个位置点改变
                    long oldValueX = m_Location.X;

                    if ( OnBeforeChangeValue( updateItem, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateItem, newValue );

                    l_ItemDelta.UpdateX();
                    if ( l_ItemDelta.IsDeltaX )
                        UpdateDelta();

                    OnAfterChangeValue( updateItem, oldValueX );

                    break;
                case UpdateBaseItemValue.Y:
                    long oldValueY = m_Location.Y;

                    if ( OnBeforeChangeValue( updateItem, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateItem, newValue );

                    l_ItemDelta.UpdateY();
                    if ( l_ItemDelta.IsDeltaY )
                        UpdateDelta();

                    OnAfterChangeValue( updateItem, oldValueY );

                    break;
                case UpdateBaseItemValue.Z:
                    long oldValueZ = m_Location.Y;

                    if ( OnBeforeChangeValue( updateItem, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateItem, newValue );

                    l_ItemDelta.UpdateZ();
                    if ( l_ItemDelta.IsDeltaZ )
                        UpdateDelta();

                    OnAfterChangeValue( updateItem, oldValueZ );

                    break;
                case UpdateBaseItemValue.Location:
                    Point3D oldValueLocation = m_Location;

                    if ( OnBeforeChangeValue( updateItem, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateItem, newValue );

                    l_ItemDelta.UpdateLocation();
                    if ( l_ItemDelta.IsDeltaLocation )
                        UpdateDelta();

                    OnAfterChangeValue( updateItem, oldValueLocation );

                    break;
                case UpdateBaseItemValue.Direction:
                    long oldValueDirection = m_Direction;

                    if ( OnBeforeChangeValue( updateItem, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateItem, newValue );

                    l_ItemDelta.UpdateDirection();
                    if ( l_ItemDelta.IsDeltaDirection )
                        UpdateDelta();

                    OnAfterChangeValue( updateItem, oldValueDirection );

                    break;
                case UpdateBaseItemValue.Serial:
                    Serial oldValueSerial = m_Serial;

                    if ( OnBeforeChangeValue( updateItem, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateItem, newValue );

                    l_ItemDelta.UpdateSerial();
                    if ( l_ItemDelta.IsDeltaSerial )
                        UpdateDelta();

                    OnAfterChangeValue( updateItem, oldValueSerial );

                    break;
                case UpdateBaseItemValue.Map:
                    BaseMap oldValueBaseMap = m_BaseMap;

                    if ( OnBeforeChangeValue( updateItem, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateItem, newValue );

                    l_ItemDelta.UpdateMap();
                    if ( l_ItemDelta.IsDeltaMap )
                        UpdateDelta();

                    OnAfterChangeValue( updateItem, oldValueBaseMap );

                    break;
                case UpdateBaseItemValue.Name:
                    string oldValueName = m_Name;

                    if ( OnBeforeChangeValue( updateItem, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateItem, newValue );

                    l_ItemDelta.UpdateName();
                    if ( l_ItemDelta.IsDeltaName )
                        UpdateDelta();

                    OnAfterChangeValue( updateItem, oldValueName );

                    break;
                case UpdateBaseItemValue.Visible:
                    bool oldValueVisible = m_Visible;

                    if ( OnBeforeChangeValue( updateItem, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateItem, newValue );

                    l_ItemDelta.UpdateVisible();
                    if ( l_ItemDelta.IsDeltaVisible )
                        UpdateDelta();

                    OnAfterChangeValue( updateItem, oldValueVisible );

                    break;
                case UpdateBaseItemValue.Parent:
                    object oldValueParent = m_Parent;

                    if ( OnBeforeChangeValue( updateItem, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateItem, newValue );

                    l_ItemDelta.UpdateParent();
                    if ( l_ItemDelta.IsDeltaParent )
                        UpdateDelta();

                    OnAfterChangeValue( updateItem, oldValueParent );

                    break;
                case UpdateBaseItemValue.Layer:
                    Layer oldValueLayer = m_Layer;

                    if ( OnBeforeChangeValue( updateItem, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateItem, newValue );

                    l_ItemDelta.UpdateLayer();
                    if ( l_ItemDelta.IsDeltaLayer )
                        UpdateDelta();

                    OnAfterChangeValue( updateItem, oldValueLayer );

                    break;
                case UpdateBaseItemValue.IsVirtualItem:
                    bool oldValueIsVirtualItem = m_IsVirtualItem;

                    if ( OnBeforeChangeValue( updateItem, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateItem, newValue );

                    l_ItemDelta.UpdateIsVirtualItem();
                    if ( l_ItemDelta.IsDeltaIsVirtualItem )
                        UpdateDelta();

                    OnAfterChangeValue( updateItem, oldValueIsVirtualItem );

                    break;
                case UpdateBaseItemValue.ItemDelta:
                    IItemDelta oldValueItemDelta = m_ItemDelta;

                    if ( OnBeforeChangeValue( updateItem, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateItem, newValue );

                    l_ItemDelta.UpdateItemDelta();
                    if ( l_ItemDelta.IsDeltaItemDelta )
                        UpdateDelta();

                    OnAfterChangeValue( updateItem, oldValueItemDelta );

                    break;
                default:

                    break;
            }


            return true;
        }
        #endregion

        #endregion

        #region zh-CHS 创建一个新的自身道具 | en Method
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private ConstructorInfo m_ConstructorInfo = null;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public object CreateNewInstance()
        {
            if ( m_ConstructorInfo != null )
            {
                object l_ReturnObject = m_ConstructorInfo.Invoke( null );

                BaseItem l_BaseItem = l_ReturnObject as BaseItem;
                if ( l_BaseItem == null )
                {
                    Debug.WriteLine( "BaseItem.CreateNewInstance(...) - l_BaseItem == null error!" );
                    return null;
                }

                return l_ReturnObject;
            }

            Type l_Type = GetType();
            ConstructorInfo[] l_ConstructorInfoArray = l_Type.GetConstructors();

            foreach ( ConstructorInfo l_ConstructorInfo in l_ConstructorInfoArray )
            {
                ParameterInfo[] l_ParameterInfoArray = l_ConstructorInfo.GetParameters();
                if ( l_ParameterInfoArray.Length == 0 )
                {
                    m_ConstructorInfo = l_ConstructorInfo;

                    object l_ReturnObject = m_ConstructorInfo.Invoke( null );

                    BaseItem l_BaseItem = l_ReturnObject as BaseItem;
                    if ( l_BaseItem == null )
                    {
                        Debug.WriteLine( "BaseMobile.CreateNewInstance(...) - l_BaseMobile == null error!" );
                        return null;
                    }

                    return l_ReturnObject;
                }
            }

            return null;
        }
        #endregion

        #region zh-CHS 人物的主处理行为 | en
        /// <summary>
        /// Delta
        /// </summary>
        /// <param name="flags"></param>
        public void UpdateDelta()
        {
            if ( m_BaseMap == null || m_BaseMap == BaseMap.NullMap || m_Deleted )
                return;

            if ( m_ItemDelta.LoginDeltaQueue() == false )
                return;

            Monitor.Enter( s_LockDeltaQueue );
            {
                s_DeltaQueue.Enqueue( this );
            }
            Monitor.Exit( s_LockDeltaQueue );

            //BaseWorld.SetSignal();
            // 需要保存一个引用的副本,防止多线程添加的时候调用失败的可能
            //BaseWorld[] l_BaseWorldArray = BaseServer.World;
            //for ( int iIndex = 0; iIndex < l_BaseWorldArray.Length; iIndex++ )
            //    l_BaseWorldArray[iIndex].SetWorldSignal();
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void ProcessDelta()
        {
        }
        #endregion

        #endregion

        #region zh-CHS 共有静态方法 | en Public Static Methods
        #region zh-CHS 私有静态成员变量 | en Private Static Member Variables
        /// <summary>
        /// 处理道具的列表
        /// </summary>
        private static Queue<BaseItem> s_DeltaQueue = new Queue<BaseItem>();
        /// <summary>
        /// 
        /// </summary>
        private static object s_LockDeltaQueue = new object();
        #endregion
        /// <summary>
        /// 处理Delta
        /// </summary>
        public static void ProcessDeltaQueue()
        {
            // 使用数组减少锁定时间
            BaseItem[] baseItemArray = null;

            if ( Monitor.TryEnter( s_LockDeltaQueue ) == false ) return;
            {
                if ( s_DeltaQueue.Count > 0 )
                {
                    baseItemArray = s_DeltaQueue.ToArray();
                    s_DeltaQueue.Clear();
                }
            }
            Monitor.Exit( s_LockDeltaQueue );

            // 如果没有需要处理的数据则返回
            if ( baseItemArray == null )
                return;

            foreach ( BaseItem baseItem in baseItemArray )
                baseItem.ProcessDelta();
        }
        #endregion

        #region zh-CHS 接口实现 | en Interface Implementation
        /// <summary>
        /// 
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public int CompareTo( IEntity other )
        {
            if ( other == null )
                return 1;

            return m_Serial.CompareTo( other.Serial );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public int CompareTo( BaseItem other )
        {
            return CompareTo( other as IEntity );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public int CompareTo( object xObject )
        {
            return CompareTo( xObject as IEntity );
        }
        #endregion
    }
}
#endregion